package com.gome.axwl.aoc.facade.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gome.axwl.aoc.common.constants.AppVersionConstants;
import com.gome.axwl.aoc.common.util.BeanJsonUtil;
import com.gome.axwl.aoc.common.util.XskyS3Util;
import com.gome.axwl.aoc.entity.driver.DriverAccount;
import com.gome.axwl.aoc.entity.dto.AppVersionDto;
import com.gome.axwl.aoc.entity.dto.PageParamDto;
import com.gome.axwl.aoc.entity.dto.PageResultDto;
import com.gome.axwl.aoc.entity.po.AppVersionPo;
import com.gome.axwl.aoc.entity.po.DevicePo;
import com.gome.axwl.aoc.facade.AppVersionFacade;
import com.gome.axwl.aoc.service.AppVersionService;
import com.gome.axwl.aoc.service.DeviceService;
import com.gome.common.utils.StringUtil;
import com.gome.commons.core.ErrorCode;
import com.gome.commons.core.ResultData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * @Description: app版本管理
 * @Auther: chengh
 * @Date: 2018/4/25 13:59
 */
@Service
public class AppServiceFacadeImpl implements AppVersionFacade {

    private final static Logger log = LoggerFactory.getLogger(AppServiceFacadeImpl.class);

    @Autowired
    private AppVersionService appVersionService;

    @Autowired
    private DeviceService deviceService;

    @Value("${app.appKey}")
    private String appKey;

    @Value("${push.url}")
    private String pushUrl;
    /**
     * 新增版本信息
     *
     * @param appVersionDto
     * @return
     */
    @Transactional
    @Override
    public ResultData add(AppVersionDto appVersionDto) {
        try {
            AppVersionPo appVersionPo = BeanJsonUtil.beanConvert(appVersionDto, AppVersionPo.class);
            if (appVersionService.checkVersionIsExist(appVersionPo) > 0l) {     //同系统下版本号已存在
                return new ResultData(AppVersionConstants.appVersionCodeRepeatCode, AppVersionConstants.appVersionCodeRepeatMsg);
            }
            appVersionPo.setVersionCreateTime(new Date());
            appVersionPo.setVersionStatus("0");     //0--未发布
            appVersionService.insert(appVersionPo);
            return new ResultData(ErrorCode.SUCCESS, "新增成功!");
        } catch (Exception e) {
            log.error("新增app版本失败，新增信息：{}，异常信息：{}", appVersionDto, e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();      //回滚
            return new ResultData(ErrorCode.ADD_FAILOR, ErrorCode.ADD_FAILOR_MSG);
        }
    }

    /**
     * 删除版本信息
     *
     * @param id
     * @return
     */
    @Transactional
    @Override
    public ResultData delete(int id) {
        try {
            AppVersionPo appVersionPo = appVersionService.selectById(id);
            appVersionService.deleteById(id);
            XskyS3Util.deleteFile(appVersionPo.getSaveFileName() + ".apk");      //删除apk文件
            XskyS3Util.deleteFile(appVersionPo.getSaveFileName() + ".xlsx");     //删除excel文件
            return new ResultData(ErrorCode.SUCCESS, "删除成功!");
        } catch (Exception e) {
            log.error("删除app版本失败，删除条件：{}，异常信息：{}", id, e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();      //回滚
            return new ResultData(ErrorCode.DEL_FAILOR, ErrorCode.DEL_FAILOR_MSG);
        }
    }

    /**
     * 发布
     *
     * @param appVersionDto
     * @return
     */
    @Transactional
    @Override
    public ResultData publish(AppVersionDto appVersionDto) {
        try {
            AppVersionPo appVersionPo = appVersionService.selectById(appVersionDto.getId());   //当前发布版本的信息
            //----------------定义消息推送发送公共结构-------开始------------
            RestTemplate restTemplate = new RestTemplate();
            org.springframework.util.MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
            form.add("method", "commonmessage.push");// <--指定方法名称
            form.add("format", "json");// <--指定数据格式
            form.add("v", "3.1");// 版本号
            form.add("appKey", "20171120");// 版本号
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("appId", appKey);                //"推送来源方标识",
            jsonObject.put("pushType", "app_update"); //"推送任务标注"
            jsonObject.put("title", "发现新版本:" + appVersionPo.getVersionName());   //"push通知标题"
            jsonObject.put("content", appVersionPo.getVersionUpdateContent());      //"push通知内容"
            jsonObject.put("iconUrl", "");      // " push通知图标------暂时预留传空值
            jsonObject.put("type", 1);         // 0-1//1-使用透传推送，0-使用通知推送
            jsonObject.put("configType", 2);
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("news_type", "3");
            jsonObject1.put("version_num", appVersionPo.getVersionCode());
            jsonObject.put("ext", JSONObject.toJSONString(jsonObject1));          //透传消息内容
            //----------------定义消息推送发送公共结构------结束-------------
            if (appVersionPo.getVersionPushScope().equals("0")) {         //全员推送---查询出所有设备，然后全部推送消息
                Integer type = appVersionPo.getVersionSystemType().equals("0") ? 1 : 0;
                List<DevicePo> devicePoList = deviceService.selectAllBySysType(type);       //全推的时候---每次只查找当前系统类型的设备
                if (CollectionUtils.isEmpty(devicePoList)) {
                    AppVersionPo appVersionPo1 = new AppVersionPo();
                    appVersionPo1.setId(appVersionDto.getId());
                    appVersionPo1.setVersionStatus("1");         //1---已发布
                    appVersionService.updateVersionStatus(appVersionPo1);
                    return new ResultData(ErrorCode.SUCCESS, "发布成功!");
                }
                Integer listSize = devicePoList.size();
                Integer size = (int) Math.ceil(devicePoList.size() / 100);        //100个为一个单位发一次推送消息（避免消息体过长）
                for (int i = 0; i <= size; i++) {
                    List<JSONObject> simpleUserList = new ArrayList<>();
                    int startIndex = i * 100;
                    int endIndex = (i + 1) * 100;
                    for (int j = startIndex; j < endIndex && j < listSize; j++) {
                        DevicePo devicePo = devicePoList.get(j);
                        JSONObject simpleUser = new JSONObject();
                        simpleUser.put("cId", devicePo.getCid());
                        simpleUser.put("userId", devicePo.getEmpNo());
                        simpleUser.put("cType", devicePo.getType());
                        simpleUserList.add(simpleUser);
                    }
                    jsonObject.put("simpleUserList", simpleUserList);
                    form.add("params", JSONObject.toJSONString(jsonObject));
                    String response = restTemplate.postForObject(pushUrl, form, String.class);
                    log.info("调用消息推送服务结果:{},参数为:{}", response, form.toString());
                }
            } else {              //部分DC推送
                String dcCodesString = appVersionPo.getVerisonDcPath();
                String[] dcCodes = dcCodesString.split(",");
                List<String> dcCodeList = Arrays.asList(dcCodes);       //dc编码集合
                ResultData<List<DriverAccount>> resultData = appVersionService.getDriversByDcCodes(dcCodeList);
                if (!resultData.getCode().equals(ErrorCode.SUCCESS)) {
                    log.error("调用主数据根据DC集合查询用户集合服务失败");
                    return new ResultData(ErrorCode.FAILOR, "发布失败.");
                }
                List<DriverAccount> driverList = resultData.getData();       //司机账号集合
                if (CollectionUtils.isEmpty(driverList)) {        //司机账号列表为空
                    AppVersionPo appVersionPo1 = new AppVersionPo();
                    appVersionPo1.setId(appVersionDto.getId());
                    appVersionPo1.setVersionStatus("1");         //1---已发布
                    appVersionService.updateVersionStatus(appVersionPo1);
                    return new ResultData(ErrorCode.SUCCESS, "发布成功!");
                }
                int listSize = driverList.size();
                Integer size = (int) Math.ceil(driverList.size() / 100);        //100个为一个单位发一次推送消息（避免消息体过长）
                for (int i = 0; i <= size; i++) {
                    List<JSONObject> simpleUserList = new ArrayList<>();
                    int startIndex = i * 100;
                    int endIndex = (i + 1) * 100;
                    DevicePo devicePo = new DevicePo();
                    for (int j = startIndex; j < endIndex && j < listSize; j++) {
                        DriverAccount driverAccount = driverList.get(j);                    //司机账号信息
                        if (driverAccount == null || StringUtil.isEmpty(driverAccount.getAccountNo())) {  //司机为空
                            continue;
                        }
                        devicePo.setEmpNo(driverAccount.getAccountNo());
                        DevicePo devicePo1 = deviceService.selectSelective(devicePo);       //司机设备信息
                        if (devicePo1 == null || com.gome.common.utils.StringUtil.isEmpty(devicePo1.getCid())) {  //当前司机没有设备信息
                            continue;
                        }
                        Integer type = appVersionPo.getVersionSystemType().equals("0") ? 1 : 0;
                        if (devicePo1.getType() != type) {           //当前司机的设备类型不是需要升级的设备类型
                            continue;
                        }
                        JSONObject simpleUser = new JSONObject();
                        simpleUser.put("cId", devicePo1.getCid());
                        simpleUser.put("userId", driverAccount.getAccountNo());
                        simpleUser.put("cType", devicePo1.getType());
                        simpleUserList.add(simpleUser);
                    }
                    if (CollectionUtils.isEmpty(simpleUserList)) {     //推送用户集合为空
                        continue;
                    }
                    jsonObject.put("simpleUserList", simpleUserList);
                    form.remove("params");
                    form.add("params", JSONObject.toJSONString(jsonObject));
                    String response = restTemplate.postForObject(pushUrl, form, String.class);
                    log.info("调用消息推送服务结果:{},参数为:{}", response, form.toString());
                }
            }
            AppVersionPo appVersionPo1 = new AppVersionPo();
            appVersionPo1.setId(appVersionDto.getId());
            appVersionPo1.setVersionStatus("1");         //1---已发布
            appVersionService.updateVersionStatus(appVersionPo1);
            return new ResultData(ErrorCode.SUCCESS, "发布成功!");
        } catch (Exception e) {
            log.error("发布app版本失败，发布版本编号：{}，异常信息：{}", appVersionDto.getVersionCode(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();      //回滚
            return new ResultData(ErrorCode.UPDATE_FAILOR, "发布失败.");
        }
    }

    /**
     * 查询列表
     *
     * @param pageParamDto
     * @return
     */
    @Override
    public ResultData getList(PageParamDto pageParamDto) {
        try {
            PageHelper.startPage(pageParamDto.getPageNum(), pageParamDto.getPageSize());   //设置分页参数
            List<AppVersionPo> appVersionPos = appVersionService.getListByPage();                //查询
            PageInfo<AppVersionPo> pageInfo = new PageInfo<>(appVersionPos);
            PageResultDto<AppVersionDto> pageResultDto = new PageResultDto<>();
            List<AppVersionDto> datas = BeanJsonUtil.listConvert(appVersionPos, AppVersionDto.class);
            pageResultDto.setData(datas);
            pageResultDto.setPageCount(pageInfo.getPages());
            pageResultDto.setPageNum(pageInfo.getPageNum());
            pageResultDto.setTotal(pageInfo.getTotal());
            return new ResultData<>(ErrorCode.SUCCESS, ErrorCode.SUCCESS_MSG, pageResultDto);
        } catch (Exception e) {
            log.error("发布app版本失败，查询条件：{}，异常信息：{}", pageParamDto, e);
            return new ResultData(ErrorCode.UPDATE_FAILOR, "发布失败.");
        }
    }


    /**
     * 校验DC编码是否存在
     *
     * @param list
     * @return
     */
    @Override
    public ResultData<List<Integer>> checkDcCodeList(List<String> list) {
        try {
            //校验dcCodeList是否全部正确
            List<Integer> dcCodes = new ArrayList<>();
            ResultData<Map<String, Object>> resultData = appVersionService.getDcByDcCodes(list);
            Map<String, Object> dcMap = resultData.getData();
            for (int i = 0; i < list.size(); i++) {
                if (!dcMap.containsKey(list.get(i))) { //dc编码不存在
                    dcCodes.add(i);
                }
            }
            return new ResultData<>(ErrorCode.SUCCESS, ErrorCode.SUCCESS_MSG, dcCodes);
        } catch (Exception e) {
            log.error("检验DC编码是否存在失败，dc集合：{}, 异常信息：{}", list.toString(), e);
            return new ResultData(ErrorCode.FAILOR, ErrorCode.FAILOR_MSG);
        }
    }

    /**
     * 是否需要更新
     *
     * @param accountNo
     * @param dcNo
     * @param versionCode
     * @param versionSystemType
     * @return
     */
    @Override
    public ResultData<AppVersionDto> checkUpdate(String accountNo, String dcNo, String versionCode, String versionSystemType) {
        try {
            //检查是否需要更新
            List<AppVersionPo> appVersionPoList = appVersionService.getBiggerVersion(versionSystemType, versionCode);
            if (appVersionPoList.size() > 0) {
                log.info("检测更新查询出的版本信息个数:{}，内容为:{} ", appVersionPoList.size(), appVersionPoList);
            }
            if (appVersionPoList.size() > 1) {       //如果有更高版本----排除掉自己的版本(集合中最后一个为自己本身版本信息)
                for (int i = 0; i < appVersionPoList.size() - 1; i++) {
                    AppVersionPo appVersionPo = appVersionPoList.get(i);
                    if (appVersionPo.getVersionPushScope().equals("0")) {         //如果更高版本有全员推送的
                        AppVersionDto appVersionDto = BeanJsonUtil.beanConvert(appVersionPo, AppVersionDto.class);
                        log.info("用户账号:{} 需要升级(全员升级),系统类型:{},当前版本:{},最新版本:{},返回信息:{}", accountNo, versionSystemType, versionCode, appVersionDto.getVersionCode(), appVersionDto.toString());
                        return new ResultData<>(ErrorCode.SUCCESS, ErrorCode.SUCCESS_MSG, appVersionDto);
                    } else {
                        if (StringUtil.isEmpty(dcNo)) {         //用户没有DC编码
                            continue;
                        }
                        if (appVersionPo.getVerisonDcPath().indexOf(dcNo) != -1) {     //不是全员推送肯定有DC域，更高版本的dc编码中有当前用户的dc
                            AppVersionDto appVersionDto = BeanJsonUtil.beanConvert(appVersionPo, AppVersionDto.class);
                            log.info("用户账号:{} 需要升级(部分升级),系统类型:{},当前版本:{},最新版本:{}, 返回信息:{}", accountNo, versionSystemType, versionCode, appVersionDto.getVersionCode(), appVersionDto.toString());
                            return new ResultData<>(ErrorCode.SUCCESS, ErrorCode.SUCCESS_MSG, appVersionDto);
                        }
                    }
                }
            }
            if (appVersionPoList.size() > 0) {
                AppVersionDto appVersionDto = BeanJsonUtil.beanConvert(appVersionPoList.get(appVersionPoList.size() - 1), AppVersionDto.class);
                return new ResultData(ErrorCode.SUCCESS, ErrorCode.SUCCESS_MSG, appVersionDto);
            } else {
                return new ResultData(ErrorCode.SUCCESS, ErrorCode.SUCCESS_MSG);
            }
        } catch (Exception e) {
            log.error("检测当前用户是否需要更新失败，当前系统：{}，当前版本: {}, 异常信息：{}", versionSystemType, versionCode, e);
            return new ResultData(ErrorCode.FAILOR, ErrorCode.FAILOR_MSG);
        }
    }
}
